
  <!DOCTYPE html>
  <html lang="en">

  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body>
    <div id="app"></div>
    <br />
    <div id="app1"></div>
    <script src="../js/babel.min.js"></script>
    <script src="../js-new/react.development.js"></script>
    <script src="../js-new/react-dom.development.js"></script>
    <script type="text/babel">
    class Demo extends React.Component {
      /**
       * @description 构造器钩子
       */
      constructor(props) {
        console.log("demo constructor");
        super(props);
        this.state = { count: 0 };
      }
      /**
       * @description 累加
       */
      add = () => {
        let { count } = this.state;
        count++;
        this.setState({ count });
      };
      /**
       * @description 强制更新
       */
      force = () => {
        this.forceUpdate();
      };
      /**
       * @description 组件将要被渲染
       */
      //  UNSAFE_componentWillMount() {
      //   console.log("demo componentWillMount");
      // }
      /**
       * @description 组件渲染完成之后调用，只调用一次
       */
      componentDidMount() {
        console.log("demo componentDidMount");
      }
      death = () => {
        ReactDOM.unmountComponentAtNode(document.getElementById("app"));
      };
      /**
       * @description 组件将要被卸载时调用
       */
      componentWillUnmount() {
        console.log("demo componentWillUnmount");
      }
      /**
       * @description 组件是否更新 进行判断，返回布尔值
       */
      shouldComponentUpdate() {
        console.log("demo shouldComponentUpdate");
        return true;
      }
      /**
       * @description 组件将要更新
       */
      //  UNSAFE_componentWillUpdate() {
      //   console.log("demo componentWillUpdate");
      // }
      /**
       * @description 组件更新
       * @param preProps 更改之前的props
       * @param preState 更改之前的state
       * @param snapshot getSnapshotBeforeUpdate钩子返回的快照值
       */
      componentDidUpdate(preProps, preState, snapshot) {
        console.log('preProps = ', preProps)
        console.log('preState = ', preState)
        console.log("snapshot = ", snapshot)
        console.log("demo componentDidUpdate");
      }
      /**
       * @description 获取props当中派生的state，在构造器之后调用
      */
      static getDerivedStateFromProps(props, state) {
        console.log("demo getDerivedStateFromProps")
        console.log("props = ", props)
        console.log("state = ", state)
        return state
        // 返回值为props的时候，state的值将会改变为从props当中取值
        // return props
        // return { count : 100}
      }
      /**
       * @description 更新之前获取快照
      */
      getSnapshotBeforeUpdate() {
        console.log("demo getSnapshotBeforeUpdate")
        // return null
        return "黄月月"
      }
      render() {
        console.log("demo render");
        return (
          <div>
            <h3 style={{ opacity: this.state.opacity }}>
              count = {this.state.count}
            </h3>
            <button onClick={this.death}>销毁组件</button><br />
            <button onClick={this.add}>+1</button><br />
            <button onClick={this.force}>强制更新</button>
          </div>
        );
      }
    }
    /**
     * @description 父组件 通过父组件传值修改子组件值
    */
    class Parent extends React.Component {
      state = { name: "黄阅阅" }
      changeNamae = () => {
        this.setState({ name: "黄月月" })
      }
      render() {
        console.log("parent render")
        return (<div>
          <h1>Parent</h1>
          <button onClick={this.changeNamae}>changeName</button>
          <Son name={this.state.name} />
        </div>)
      }
    }
    class Son extends React.Component {
      /**
       * @description 将要接收到父组件的props (第一次传递不会触发该钩子)
      */
      // UNSAFE_componentWillReceiveProps(props) {
      //   console.log("son will props", props)
      // }
      render() {
        console.log("son render")
        return (<div><h1>Son</h1><h3>parent name = {this.props.name}</h3></div>)
      }
    }
    ReactDOM.render(<Demo />, document.getElementById("app"));
    ReactDOM.render(<Parent />, document.getElementById("app1"));
    </script>
  </body>
  <!--
    https://zh-hans.reactjs.org/blog/2018/03/27/update-on-async-rendering.html
    
    我们得到最重要的经验是，过时的组件生命周期往往会带来不安全的编码实践，具体函数如下：
      - componentWillMount
      - componentWillReceiveProps
      - componentWillUpdate

      这些生命周期方法经常被误解和滥用；此外，我们预计，在异步渲染中，它们潜在的误用问题可能更大。
      我们将在即将发布的版本中为这些生命周期添加 “UNSAFE_” 前缀。（这里的 “unsafe” 不是指安全性，
      而是表示使用这些生命周期的代码在 React 的未来版本中更有可能出现 bug，尤其是在启用异步渲染之后。）
  -->

  </html>
